home *** CD-ROM | disk | FTP | other *** search
- From: enevill@acorn.co.uk (Edward Nevill)
- Subject: Re: Modules in C
- Date: 4 Oct 91 14:01:06 GMT
-
- In article <1991Oct01.212021.16581@demon.co.uk> pmoore@cix.compulink.co.uk (Paul Moore) writes:
-
- >The second problem is more of a pain. I have worked out that I should
- >declare my vector handler to CMHG as an IRQ handler, so that I get the
- >proper veneer round my code. BUT... the vector I want to claim is (you
- >guessed it!) OS_ReadLine, which requires the C flag to be set on exit
- >based on the results of the call. As far as I can see, the standard
- >veneer does not allow the setting of flags on return.
- >
- >As far as I can see, the only way round this is to write my own entry
- >veneer for the handler. However, I'm not 100% sure what the 'standard'
- >veneer does. I can probably work it out by disassembling the code
- >generated by CMHG, but can anybody *tell* me what it does - to save me
- >some work? If so, I'd be very grateful. Also, maybe later versions of
- >CMHG would benefit from an extra keyword 'irq-handlers-c' or some such?
- >
-
- irq_entry STMDB sp!, {r0-r9, sl, fp, lr} ; Save regs on IRQ | SVC stack
- MOV r0, sp ; Set up _kernel_swi_regs * argument
- + ADD r2, sp, #12 * 4 ; Set up pointer to carry arg (= LR!!!)
- MOV r6, pc
- BIC r6, r6, #3
- TEQP r3, #3 ; To SVC mode, preserve IRQ / FIQ state
- MOV fp, #0 ; Halt C backtrace at this stack level
- MOV r7, lr ; Save SVC lr
- MOV sl, sp, LSR #20
- MOV sl, sl, ASL #20 ; Get LWM of SVC stack
- LDMIA sl, {r4, r5} ; Save static data relocations across fn call
- MOV r1, r12 ; Set up private workspace argument
- LDR r12, [r12] ; Get pointer to static relocations for module
- LDMIB r12, {r12, lr} ; IB skips first word
- STMIA sl, {r12, lr} ; Set up static data relocations
- ADD sl, sl, #512+40 ; 40 = size of stack chunk structure
- BL c_function ; Do the function
- SUB sl, sl, #512+40 ; Point back to base of SVC stack
- STMIA sl, {r4, r5} ; Restore old static data relocations
- MOV lr, r7 ; Restore SVC lr
- TEQP r6, #0 ; Back to entry mode
- CMPS r0, #0 ; Intercept?
- LDMNEIA sp!, {r0-r9, sl, fp, pc}^ ; No (carry arg will not be written!!!)
- - LDMIA sp!, {r0-r9, sl, fp, lr, pc}^ ; Yes
- + LDMIA sp!, {r0-r9, sl, fp, ip, lr} ; Yes (ip = carry value to ret)
- + BIC lr, lr, #1:SHL:29
- + CMP ip, #0
- + ORRNE lr, lr, #1:SHL:29
- + MOVS pc, lr
-
- The veneer genererated for an IRQ handler by cmhg is something like the above
- without the '+' lines. Remove the '-' line and add the '+' lines to produce a
- veneer which allows you to return the carry flag.
-
- The declaration the a handler using this looks something like
-
- int c_function(_kernel_swi_regs *r, void *pw, int *carry);
-
- NOTE: you must not write the carry arg unless you are intercepting the call
- (ie you are returning 0 from c_function). Doing so will lead to disaster
- (it will continue executing at the address you write to carry, so if you
- write 0 it will continue executing at location 0!!!). I may consider making
- this more robust in a later version.
-
- To claim the vector in your init code
-
- extern int irq_entry;
-
- _kernel_oserror *user_init(char *cmd_tail, int podule_base, void *pw)
- {
- _kernel_swi_regs r;
- ...
- r.r[0] = 0x0e; /* ReadLineV */
- r.r[1] = (int)&irq_entry;
- r.r[2] = (int)pw;
- _kernel_swi(OS_Claim, &r, &r);
- ...
- return 0;
- }
-
- NOTE: If you claim a vector in your initialisation code like this you must
- either return 0 indicating no error or release the vector before returning an
- error (your finalisation is not called if there is an error in initialisation).
-
- Have fun,
- Edward.
-
-